package com.xinruke.hostels.dailymanage.service;

import com.xinruke.hostels.common.cache.ManageUserCache;
import com.xinruke.hostels.common.constants.SysDicConstant;
import com.xinruke.hostels.common.exception.BizException;
import com.xinruke.hostels.common.po.YwFangjian;
import com.xinruke.hostels.common.po.YwFangtairiqijilu;
import com.xinruke.hostels.common.po.constants.FangtaiConstants;
import com.xinruke.hostels.common.po.constants.YwFangtairiqijiluConstants;
import com.xinruke.hostels.common.util.DateCalendarUtil;
import com.xinruke.hostels.common.vo.ErrorEnum;
import com.xinruke.hostels.common.vo.ResultVO;
import com.xinruke.hostels.dailymanage.interfaces.dto.RemainCountQueryDto;
import com.xinruke.hostels.dailymanage.interfaces.dto.RoomReservationQueryDTO;
import com.xinruke.hostels.dailymanage.interfaces.dto.RoomReservationResultDTO;
import com.xinruke.hostels.dailymanage.interfaces.dto.roomclean.RoomCleanRecordAddDTO;
import com.xinruke.hostels.dailymanage.interfaces.dto.roomlock.RoomLockRecordAddDTO;
import com.xinruke.hostels.dailymanage.interfaces.dto.roomrepair.RoomRepairRecordAddDTO;
import com.xinruke.hostels.dailymanage.interfaces.dto.roomstatus.*;
import com.xinruke.hostels.dailymanage.interfaces.dto.roomstatuschange.RoomStatusChangeRecordAddDTO;
import com.xinruke.hostels.dailymanage.mapper.YwFangjianMapper;
import com.xinruke.hostels.dailymanage.mapper.YwFangtairiqijiluMapper;
import com.xinruke.hostels.dailymanage.mapper.YwRuzhuDingdanMapper;
import com.xinruke.hostels.dailymanage.mapper.YwRuzhuDingdanZixiangMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * @author yutaipu
 */
@Service
public class RoomStatusService {

    @Autowired
    private RoomCleanRecordService roomCleanRecordService;

    @Autowired
    private RoomRepairRecordService roomRepairRecordService;

    @Autowired
    private RoomLockRecordService roomLockRecordService;

    @Autowired
    private RoomStatusChangeRecordService roomStatusChangeRecordService;

    @Autowired
    private YwFangjianMapper ywFangjianMapper;

    @Autowired
    private YwRuzhuDingdanMapper ywRuzhuDingdanMapper;

    @Autowired
    private YwRuzhuDingdanZixiangMapper ywRuzhuDingdanZixiangMapper;

    @Resource
    private YwFangtairiqijiluMapper ywFangtairiqijiluMapper;

    @Autowired
    private ManageUserCache manageUserCache;

    /**
     * 查询酒店下每个房间状态下的数量
     */
    public ResultVO<List<RSGetRoomCountQueryResultDTO>> getRoomStatusCount(RSGetRoomCountQueryDTO params) {
        List<RSGetRoomCountQueryResultDTO> list = ywFangjianMapper.getRoomStatusCount(manageUserCache.getJiudianId());
        return ResultVO.success("获取成功", list);
    }

    /**
     * 查询房间列表
     */
    public ResultVO<RSListRoomQueryResultDTO> listRoom(RSListRoomQueryDTO params) {

        Integer jiudianId = manageUserCache.getJiudianId();
        List<RSBuildingDetailDTO> buildingList = ywFangjianMapper.listRoom(params, jiudianId);

        Date beginDate = DateCalendarUtil.getTodayBegin();
        Date endDate = DateCalendarUtil.getTodayEnd();

        // 今天预离的房间列表
        List<RSCheckInDetailQueryResultDTO> leftTodayList = ywRuzhuDingdanZixiangMapper.listLeftToday(jiudianId, beginDate, endDate);

        // 已经入住的房间列表
        List<RSCheckInDetailQueryResultDTO> checkInRoomList = ywRuzhuDingdanZixiangMapper.listCheckInRoom(jiudianId);

        // 获取今日预抵的房间列表
        List<RSArriveTodayRoomDTO> todayArriveRoomIdList = ywFangtairiqijiluMapper.listRoomIdWithDate(jiudianId, beginDate, endDate);

        // 现在入住的总人数
        int peopleCount = ywRuzhuDingdanMapper.getCheckInPeopleCount(jiudianId);

        int roomCount = 0;

        for (RSBuildingDetailDTO building : buildingList) {
            for (RSFloorDetailDTO floor : building.getLoucengList()) {
                // 房间数
                roomCount += floor.getFangjianList().size();
                for (RSRoomDetailDTO room : floor.getFangjianList()) {
                    // 已经入住的房间
                    for (RSCheckInDetailQueryResultDTO checkInDetail : checkInRoomList) {
                        if (room.getFangjianId().equals(checkInDetail.getFangjianId())) {
                            room.setRuzhuleixing(checkInDetail.getRuzhuleixing());
                            room.setYudingleixing(checkInDetail.getKeyuanleixing());
                            room.setYajin(checkInDetail.getYajin());
                            break;
                        }
                    }
                    // 今日预离
                    for (RSCheckInDetailQueryResultDTO checkInDetail : leftTodayList) {
                        if (room.getFangjianId().equals(checkInDetail.getFangjianId())) {
                            room.setLikaishijian(checkInDetail.getLikaishijian());
                            break;
                        }
                    }
                    // 今日预抵
                    for (RSArriveTodayRoomDTO todayArriveRoom : todayArriveRoomIdList) {
                        if (room.getFangjianId().equals(todayArriveRoom.getFangjianId())) {
                            room.setDidashijian(todayArriveRoom.getDidashijian());
                            break;
                        }
                    }
                }
            }
        }

        RSListRoomQueryResultDTO resultDTO = new RSListRoomQueryResultDTO();
        resultDTO.setZongfangjianshu(roomCount);
        resultDTO.setDangqianruzhurenshu(peopleCount);
        BigDecimal checkInRatio = checkInRoomList.size() == 0 ? BigDecimal.ZERO : new BigDecimal(checkInRoomList.size()).divide(new BigDecimal(roomCount), 2, RoundingMode.DOWN);
        resultDTO.setDanqianruzhulv(checkInRatio.multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN) + "%");
        resultDTO.setLoudongList(buildingList);
        return ResultVO.success("获取房间列表成功", resultDTO);
    }

    public ResultVO<RSCheckInDetailQueryResultDTO> getCheckInDetail(RSCheckInDetailQueryDTO params) {
        RSCheckInDetailQueryResultDTO dto = ywRuzhuDingdanZixiangMapper.getDetail(params);
        if (null == dto) {
            return ResultVO.fail("当前房间没有入住信息");
        }
        return ResultVO.success("获取入住详情成功", dto);
    }

    /**
     * 查询指定房型在指定时间的余房数
     */
    public ResultVO<Integer> queryRemainRoomCount(RemainCountQueryDto params) {
        ResultVO<Integer> resultVO = ResultVO.success();
        Integer count = ywFangtairiqijiluMapper.queryRemainRoomCount(params);
        resultVO.setData(count);
        return resultVO;
    }

    public ResultVO<RoomReservationResultDTO> roomReservation(RoomReservationQueryDTO params) {
        ResultVO<RoomReservationResultDTO> resultVO = ResultVO.fail();
        //随机分房
        RoomReservationResultDTO resultDTO = ywFangtairiqijiluMapper.selectRandomRoomId(params);
        if (resultDTO == null) {
            //throw new ArgumentException("房间没有库存了");
            resultVO.setMessage("房间没有库存了");
            return resultVO;
        }

        //锁房
        YwFangtairiqijilu fangtairiqijilu = new YwFangtairiqijilu();
        fangtairiqijilu.setShanchubiaoshi(SysDicConstant.DELFLAG_0);
        fangtairiqijilu.setJiudianId(params.getJiudianId());
        fangtairiqijilu.setFangjianId(resultDTO.getRoomId());
        fangtairiqijilu.setKaishishijian(params.getStartTime());
        fangtairiqijilu.setJieshushijian(params.getEndTime());
        fangtairiqijilu.setYewuyuanId(params.getOrderId());

        fangtairiqijilu.setFangjianzhuangtai(YwFangtairiqijiluConstants.FANGJIANZHUANGTAI_SUOFANG);
        fangtairiqijilu.setFangjianleibie(YwFangtairiqijiluConstants.FANGJIANLEIBIE_FANGJIAN);
        fangtairiqijilu.setYewuleixing(YwFangtairiqijiluConstants.YEWULEIXING_WANGSHANGYUDINGDAN);
        fangtairiqijilu.setZhuangtai(YwFangtairiqijiluConstants.ZHUANGTAI_YOUXIAO);
        fangtairiqijilu.setCaozuobiaoshi(YwFangtairiqijiluConstants.CAOZUOBIAOSHI_YUDINGSUOFANG);
        fangtairiqijilu.setShanchubiaoshi(SysDicConstant.DELFLAG_0);

        fangtairiqijilu.setBeizhu("预订锁房");
        fangtairiqijilu.setChuangjianshijian(new Date());
        fangtairiqijilu.setGengxinshijian(new Date());
        int insert = ywFangtairiqijiluMapper.insert(fangtairiqijilu);
        if (insert > 0) {
            resultVO = ResultVO.success();
            resultVO.setData(resultDTO);
            return resultVO;
        }
        return resultVO;
    }

    /**
     * 置净
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVO setClean(RSSetCleanDTO params) {

        YwFangjian room = ywFangjianMapper.selectByPrimaryKey(params.getFangjianId());

        if (!room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGZANG) &&
                !room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_ZHUZANG)) {
            return ResultVO.fail(room.getFangjianbianhao() + "房间当前状态不支持置净");
        }

        YwFangjian update = new YwFangjian();
        update.setId(params.getFangjianId());

        byte newStatus;
        if (room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGZANG)) {
            // 住脏-住净
            newStatus = FangtaiConstants.FANGJIANZHUANGTAI_KONGJING;
        } else if (room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_ZHUZANG)) {
            // 空脏-空净
            newStatus = FangtaiConstants.FANGJIANZHUANGTAI_ZHUJING;
        } else {
            return ResultVO.fail(room.getFangjianbianhao() + "房间当前状态不支持置净");
        }
        ywFangjianMapper.updateStatusById(room.getId(), newStatus);

        // 添加放扫日志记录
        RoomCleanRecordAddDTO cleanDTO = new RoomCleanRecordAddDTO();
        BeanUtils.copyProperties(params, cleanDTO);
        cleanDTO.setFangjianhao(room.getFangjianbianhao());
        cleanDTO.setFangxing(room.getFangxingId());
        ResultVO<Integer> addResult = roomCleanRecordService.add(cleanDTO);
        if (addResult.getCode() == ResultVO.SUCCESS) {
            RoomStatusChangeRecordAddDTO addDTO = new RoomStatusChangeRecordAddDTO();
            addDTO.setFangjianId(room.getId());
            addDTO.setFangjianbianhao(room.getFangjianbianhao());
            addDTO.setYuanzhuangtai(room.getZhuangtai());
            addDTO.setDangqianzhuangtai(update.getZhuangtai());
            addDTO.setBeizhu("置净：当前状态是" + room.getZhuangtai());
            addDTO.setKaishishijian(new Date());
            addDTO.setJieshushijian(new Date());
            addDTO.setYuanid(addResult.getData());
            addDTO.setYewuleixing((byte) 1);
            roomStatusChangeRecordService.add(addDTO);
        }

        return ResultVO.success();
    }

    /**
     * 置脏：空净和住净都能置脏，置脏后变为空脏
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVO setDirty(RSSetDirtyDTO params) {

        YwFangjian room = ywFangjianMapper.selectByPrimaryKey(params.getFangjianId());

        if (!room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGJING) &&
                !room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_ZHUJING)) {
            return ResultVO.fail(room.getFangjianbianhao() + "房间当前状态不支持置脏");
        }

        // 更新房间状态
        ywFangjianMapper.updateStatusById(room.getId(), FangtaiConstants.FANGJIANZHUANGTAI_KONGZANG);

        RoomStatusChangeRecordAddDTO addDTO = new RoomStatusChangeRecordAddDTO();
        addDTO.setFangjianId(room.getId());
        addDTO.setFangjianbianhao(room.getFangjianbianhao());
        addDTO.setYuanzhuangtai(room.getZhuangtai());
        addDTO.setDangqianzhuangtai(FangtaiConstants.FANGJIANZHUANGTAI_KONGZANG);
        addDTO.setBeizhu("置脏：当前状态是" + room.getZhuangtai());
        addDTO.setKaishishijian(new Date());
        addDTO.setJieshushijian(new Date());
        addDTO.setYuanid(null);
        addDTO.setYewuleixing((byte) 1);
        roomStatusChangeRecordService.add(addDTO);

        return ResultVO.success();
    }

    /**
     * 设置为维修
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVO setRepair(RSRepairDTO params) {
        YwFangjian room = ywFangjianMapper.selectByPrimaryKey(params.getFangjianId());

        // 房间状态不是空净或空脏不能维修
        if (!room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGJING) &&
                !room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGZANG)) {
            return ResultVO.fail("房间状态不是空净或空脏不能维修");
        }

        // 更新房间状态
        ywFangjianMapper.updateStatusById(room.getId(), FangtaiConstants.FANGJIANZHUANGTAI_WEIXIU);

        RoomRepairRecordAddDTO repairDTO = new RoomRepairRecordAddDTO();
        BeanUtils.copyProperties(params, repairDTO);
        repairDTO.setFangjianhao(room.getFangjianbianhao());
        ResultVO<Integer> addResult = roomRepairRecordService.add(repairDTO);

        if (addResult.getCode() == ResultVO.SUCCESS) {
            RoomStatusChangeRecordAddDTO addDTO = new RoomStatusChangeRecordAddDTO();
            addDTO.setFangjianId(room.getId());
            addDTO.setFangjianbianhao(room.getFangjianbianhao());
            addDTO.setYuanzhuangtai(room.getZhuangtai());
            addDTO.setDangqianzhuangtai(FangtaiConstants.FANGJIANZHUANGTAI_WEIXIU);
            addDTO.setBeizhu("维修：当前状态是" + room.getZhuangtai());
            addDTO.setKaishishijian(params.getKaishishijian());
            addDTO.setJieshushijian(params.getJieshushijian());
            addDTO.setYuanid(addResult.getData());
            addDTO.setYewuleixing((byte) 1);
            roomStatusChangeRecordService.add(addDTO);
        }
        return ResultVO.success();
    }

    /**
     * 锁房
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVO setLocked(RSLockedDTO params) {

        YwFangjian room = ywFangjianMapper.selectByPrimaryKey(params.getFangjianId());

        // 房间状态不是空净或空脏不能维修
        if (!room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGJING) &&
                !room.getZhuangtai().equals(FangtaiConstants.FANGJIANZHUANGTAI_KONGZANG)) {
            return ResultVO.fail("房间状态不是空净或空脏不能锁房");
        }

        //更新房间状态
        ywFangjianMapper.updateStatusById(room.getId(), FangtaiConstants.FANGJIANZHUANGTAI_SUOFANG);

        RoomLockRecordAddDTO lockedDTO = new RoomLockRecordAddDTO();
        BeanUtils.copyProperties(params, lockedDTO);
        lockedDTO.setFangjianhao(room.getFangjianbianhao());
        ResultVO<Integer> addResult = roomLockRecordService.add(lockedDTO);

        if (addResult.getCode() == ResultVO.SUCCESS) {
            RoomStatusChangeRecordAddDTO addDTO = new RoomStatusChangeRecordAddDTO();
            addDTO.setFangjianId(room.getId());
            addDTO.setFangjianbianhao(room.getFangjianbianhao());
            addDTO.setYuanzhuangtai(room.getZhuangtai());
            addDTO.setDangqianzhuangtai(FangtaiConstants.FANGJIANZHUANGTAI_SUOFANG);
            addDTO.setBeizhu("手动锁房：当前状态是" + room.getZhuangtai());
            addDTO.setKaishishijian(params.getKaishishijian());
            addDTO.setJieshushijian(params.getJieshushijian());
            addDTO.setYuanid(addResult.getData());
            addDTO.setYewuleixing((byte) 1);
            roomStatusChangeRecordService.add(addDTO);
        }

        return ResultVO.success();
    }

    /**
     * 批量置净
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultVO setCleanBatch(RSSetCleanBatchDTO params) {
        for (RSSetCleanDTO setCleanDTO : params.getParamsList()) {
            ResultVO resultVO = setClean(setCleanDTO);
            if (!resultVO.isSuccess()) {
                throw new BizException(ErrorEnum.ERROR_50101.getCode(), resultVO.getMessage());
            }
        }
        return ResultVO.success();
    }

    /**
     * 批量置脏
     */
    public ResultVO setDirtyBatch(RSSetDirtyBatchDTO params) {
        for (RSSetDirtyDTO setDirtyDTO : params.getParamsList()) {
            ResultVO resultVO = setDirty(setDirtyDTO);
            if (!resultVO.isSuccess()) {
                throw new BizException(ErrorEnum.ERROR_50102.getCode(), resultVO.getMessage());
            }
        }
        return ResultVO.success();
    }
}